package cool.taomu.toolkit.jersey

import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.nio.charset.StandardCharsets
import javax.inject.Inject
import javax.ws.rs.core.UriBuilder
import org.glassfish.jersey.internal.MapPropertiesDelegate
import org.glassfish.jersey.server.ApplicationHandler
import org.glassfish.jersey.server.ContainerRequest
import org.glassfish.jersey.server.ResourceConfig
import org.slf4j.LoggerFactory
import com.google.common.base.Optional

class JerseyInternalInvoker {
	val static LOG = LoggerFactory.getLogger(JerseyInternalInvoker);
	var ApplicationHandler applicationHandler;

	@Inject
	new(ResourceConfig application) {
		this.applicationHandler = new ApplicationHandler(application)
	}

	def Optional<String> invoke(RequestDto dto) throws Exception {
		LOG.info("执行Controller调用:\n{}", dto);
		if (dto === null) {
			return Optional.absent;
		}
		var baseUri = UriBuilder.fromPath("/").build();
		val requestUri = UriBuilder.fromPath(dto.serviceName)
		LOG.info("baseUri:{}", baseUri.path);
		if (dto.params !== null) {
			dto.params.forEach [ k, v |
				requestUri.queryParam(k, v.toArray);
			]
		}
		var requestUri2 = requestUri.build();
		LOG.info("requestUri2:{}", requestUri2.path);
		val ContainerRequest request = new ContainerRequest(
			baseUri,
			requestUri2,
			dto.method.toUpperCase(),
			null,
			new MapPropertiesDelegate(),
			null
		);

		if (dto.contentType !== null) {
			request.header("Content-Type", dto.contentType);
		}

		if (dto.headers !== null) {
			dto.headers.forEach [ k, v |
				request.header(k, v)
			]
		}

		if (dto.body !== null && !dto.body.isEmpty()) {
			var byte[] entityBytes = dto.body.getBytes(StandardCharsets.UTF_8);
			request.setEntityStream(new ByteArrayInputStream(entityBytes));
			request.bufferEntity();
		}

		var ByteArrayOutputStream output = new ByteArrayOutputStream();
		applicationHandler.apply(request, output).get;
		return Optional.fromNullable(output.toString(StandardCharsets.UTF_8.name()));
	}
}
